package cn.kgc.common.security.filter;



import cn.kgc.common.constant.ResultConstant;
import cn.kgc.common.util.JwtUtil;
import cn.kgc.common.util.ResponseUtil;
import cn.kgc.common.vo.Result;
import cn.kgc.api.entity.CustomerUser;
import cn.kgc.api.entity.Users;
import cn.kgc.api.form.LoginForm;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: kgc
 * @Date: 2024-04-09
 * @Description: 登录的过滤器
 * @Version: v1.0
 */
public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {

    public TokenLoginFilter(AuthenticationManager authenticationManager){
        // 设置认证管理器
        setAuthenticationManager(authenticationManager);
        //是否只支持post请求
        setPostOnly(false);
        //登录的请求地址和请求方式
        setRequiresAuthenticationRequestMatcher(
                new AntPathRequestMatcher("/users/login","POST")
        );
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            //获得登录的账号密码
            LoginForm loginForm= new ObjectMapper().readValue(request.getInputStream(), LoginForm.class);
            //封装登录的数据
            Authentication authentication=
                    new UsernamePasswordAuthenticationToken(loginForm.getUserName(),loginForm.getUserPwd());
            //使用SpringSecurity进行认证操作 （使用的是UserDetailsService接口中的方法）
            return getAuthenticationManager().authenticate(authentication);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                            FilterChain chain, Authentication authResult) throws IOException, ServletException {
        //获得登录成功的用户信息
        CustomerUser customerUser=(CustomerUser) authResult.getPrincipal();
        Users sysUser = customerUser.getSysUser();

        //生成token
        String token = JwtUtil.createToken(sysUser.getUserId() + "", sysUser.getUserName());
        //封装返回的数据
        Map<String,Object> map=new HashMap<>();
        map.put("token",token);
        map.put("userId",sysUser.getUserId());
        map.put("userName",sysUser.getUserName());
        map.put("userEmail",sysUser.getUserEmail());
        map.put("state",sysUser.getState());
        map.put("deptId",sysUser.getDeptId());
        map.put("role",sysUser.getRoleId());
        //返回令牌信息
        ResponseUtil.out(response,Result.success(map));
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        Result result = Result.builder()
                .code(ResultConstant.LOGIN_USERNAME_PASSWORD_ERROR.getCode())
                .message(ResultConstant.LOGIN_USERNAME_PASSWORD_ERROR.getMessage())
                .build();
        ResponseUtil.out(response,result);
    }
}
